<!--
/// 
/// MaDAson - Toolkit for Model Driven Software Development
///
/// Copyright [2006] Marcus Lankenau
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///  
///     http://www.apache.org/licenses/LICENSE-2.0
///  
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// 
-->
<%@ Page Language="C#" %>
<%@ Import Namespace="Madason.MetaModel" %>
<%@ Import Namespace="Madason.MetaModel.DAO" %>
using System;
using System.Collections.Generic;

namespace <%= Class.Namespace.FullName %>
{
	/// <%= "<" %>summary>
	/// <%= Class.Documentation.Replace("\n", "\n	/// ") %>
	/// <%= "<" %>/summary>
	[Serializable()]
	public <%= Abstract %>class <%= Class.Name %> <%= Class.SuperClass != null ? ": " + Class.SuperClass.ExplicitName : "" %>
	{
	
		public static <%= Class.Name %> GetInstance()
		{
			<% if (Class.FindValue("implementation") != null && Class.FindValue("implementation").Trim() != "")
	  { %>
			return new <%= Class.FindValue("implementation") %>();
			<% } else { %>
			return new <%= Class.Name %>();
			<% } %>
		}
	
	
<% foreach (StateMachine sm in Class.StateMachines) { %>
		public enum <%= sm.Name %>Enum
		{		
			Undefined,
<%   
		foreach (State state in sm.SimpleStates) {
%>		

			<%= state.Name %><%= sm.SimpleStates[sm.SimpleStates.Count-1] == state ? "" : "," %>			
<%   } %>
		}	
<% } %>	
	
	
	
<% foreach (Madason.MetaModel.Attribute attr in Class.Attributes) { %>
		<%= attr.Type.ExplicitName %> <%= "_" + attr.Name + GetInitializer(attr.Type)%>;
<% } %>
<% foreach (PersistedAssociation assoc in Class.ActiveAssociations)
   { %>
		int <%= "_" + assoc.RoleName %>;
<% } %>
<% foreach (StateMachine sm in Class.StateMachines) { %>
		<%= sm.Name %>Enum _<%= sm.Name %> = <%= sm.Name %>Enum.<%= sm.InitialState.Name %>;
<% } %>


<% foreach (Madason.MetaModel.Attribute attr in Class.Attributes) { %>
		public const string Prop<%= attr.Name %> = "<%= attr.Name %>";
<% } %>
<% foreach (PersistedAssociation assoc in Class.ActiveAssociations)
   { %>
		public const string Prop<%= assoc.RoleName %> = "<%= assoc.RoleName %>";
<% } %>


<% foreach (Madason.MetaModel.Attribute attr in Class.Attributes) { %>
		/// <%= "<" %>summary>
		/// <%= attr.Documentation.Replace("\n", "\n		/// ")%>
		/// <%= "<" %>/summary>
		public virtual <%= attr.Type.ExplicitName %> <%= attr.Name %>
		{
			get { return <%= "_"+attr.Name %>; }
			set { <%= "_"+attr.Name %> = value; }
		}
		
<% } %>

<% foreach (StateMachine sm in Class.StateMachines) { %>
		/// <%= "<" %>summary>
		/// State for Statemachine <%= sm.Name %> ")%>
		/// <%= "<" %>/summary>
		public virtual <%= sm.Name %>Enum <%= sm.Name %>
		{
			get { return <%= "_"+sm.Name %>; }
			set { <%= "_"+sm.Name %> = value; }
		}

<% } %>


<% foreach (PersistedAssociation assoc in Class.ActiveAssociations)
   { %>
		/// <%= "<" %>summary>
		/// <%= assoc.Documentation.Replace("\n", "\n		/// ")%>
		/// <%= "<" %>/summary>
		public int <%= assoc.RoleName %>
		{
			get { return <%= "_" + assoc.RoleName %>; }
			set { <%= "_" + assoc.RoleName %> = value; }
		}
		
<% } %>

		public bool Equals(<%= Class.Name %> o)
		{
<% foreach (PersistedAttribute attr in Class.Attributes) { %>		
<%   if (attr.Stereotype == Stereotype.Transient) continue; %>
			if (this.<%= attr.Name %> != o.<%= attr.Name %>) return false;
<% } %>
<% foreach(PersistedAssociation assoc in Class.ActiveAssociations) { %>		
				if (this.<%= assoc.RoleName %> != o.<%= assoc.RoleName %>) return false;
<% } %>
			return true;
		}
		
		
<% foreach (Operation op in Class.Operations) {  %>		
<%   if (op.Stereotype == Stereotype.Finder) continue; %>

		public abstract <%= op.ReturnType.ExplicitName %> <%= op.Name %>(<%= op.ParameterString %>);

<% } %>


<% foreach (string action in Class.GetUniqueStateActions()) {  %>		

		public abstract void <%= action %>();

<% } %>


<% foreach (StateMachine sm in Class.StateMachines) { %>
<%   foreach (StateTransitionTrigger trigger in sm.GetTriggerUnique()) { %>
		public void <%= trigger.Name %>()
		{
<% foreach (StateTransition trans in sm.GetTransitionsByTriggerName(trigger.Name)) { %>
			if (<%= sm.Name %> == <%= sm.Name %>Enum.<%= trans.Source.Name %>)
			{
<% foreach (StateAction action in trans.Source.ExitActions) { %>				
				<%= action.Name %>();
<% } %>
<% if (trans.Target.StateType == StateType.Branch) { %>
<% bool firstChoice = true; %>
<% foreach (StateTransition choiceTrans in trans.Target.GetTransitionsWithGuard()) { %>
				<%= firstChoice ? "" : "else " %>if (<%= choiceTrans.Guard %>)
				{
					<%= sm.Name %> = <%= sm.Name %>Enum.<%= choiceTrans.Target.Name %>;				
					<% foreach (StateAction action in choiceTrans.Target.EntryActions) { %>				
					<%= action.Name %>();		
					<% } %>
				}
<% firstChoice = false; %>				
<% } %>				
<% if (trans.Target.GetTransitionWithoutGuard() != null) { %>
				else
				{ 
					<%= sm.Name %> = <%= sm.Name %>Enum.<%= trans.Target.GetTransitionWithoutGuard().Target.Name %>;				
					<% foreach (StateAction action in trans.Target.GetTransitionWithoutGuard().Target.EntryActions) { %>				
					<%= action.Name %>();		
					<% } %>
				}
<% } %>
<% } else { %>
				<%= sm.Name %> = <%= sm.Name %>Enum.<%= trans.Target.Name %>;			
<% } %>
<% foreach (StateAction action in trans.Actions) { %>				
				<%= action.Name %>();
<% } %>				
<% foreach (StateAction action in trans.Target.EntryActions) { %>				
				<%= action.Name %>();		
<% } %>
				return;
			}
<% } %>
			throw new ApplicationException("Invalid Call '<%= trigger.Name %>' for State '"+<%= sm.Name %>.ToString()+"'");
		}
		
		
<%   } %>
<% } %>
	}
}

<script runat="server">
	private Entity @class;

	public Entity Class
	{
		get { return @class; }
		set { @class = value; }
	}	
	
	protected string GetInitializer(Class type)
	{
		if (type.Name == "DateTime") return " = DateTime.Now";
		else return "";
	}


	public string Abstract
	{
		get
		{
			if (Class.GetUniqueStateActions().Count > 0)
				return "abstract ";
			
			foreach (Operation op in Class.Operations)
			{
				if (op.Stereotype != Stereotype.Finder)
					return "abstract ";				
			}
			return "";
		}
		
	}
	
</script>